namespace System;
/// <summary>
/// ConstructorInvoker
/// </summary>
public sealed class ConstructorInvoker
{
    /// <summary>
    /// 创建函数委托
    /// </summary>
    /// <returns></returns>
    private delegate object DynamicObjectActivator();
    /// <summary>
    /// caches
    /// </summary>
    private readonly static ConcurrentDictionary<RuntimeTypeHandle, DynamicObjectActivator> cache = new ConcurrentDictionary<RuntimeTypeHandle, DynamicObjectActivator>();
    /// <summary>
    /// 创建对象
    /// </summary>
    /// <param name="t"></param>
    /// <returns></returns>
    /// <exception cref="MissingMemberException"></exception>
    public static object? Build(Type t)
    {
        if (cache.TryGetValue(t.TypeHandle, out var value))
            return value();

        var dynamicMethod = new DynamicMethod("CreateInstance", t, Type.EmptyTypes, true);

        var ilGenerator = dynamicMethod.GetILGenerator();
        ilGenerator.Emit(OpCodes.Nop);

        var ctor = t.GetConstructor(Type.EmptyTypes);
        if (ctor is null)
            throw new MissingMemberException("UnableToFindDefaultConstructor");

        ilGenerator.Emit(OpCodes.Newobj, ctor);
        ilGenerator.Emit(OpCodes.Ret);

        var doa = (DynamicObjectActivator)dynamicMethod.CreateDelegate(typeof(DynamicObjectActivator));
        cache.TryAdd(t.TypeHandle, doa);

        return doa();
    }

}